home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / decprom / RCS / fsDisk.c,v < prev    next >
Encoding:
Text File  |  1991-08-31  |  16.7 KB  |  551 lines

  1. head     1.2;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    jhh:1.2; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.2
  10. date     91.08.30.17.36.16;  author shirriff;  state Exp;
  11. branches ;
  12. next     1.1;
  13.  
  14. 1.1
  15. date     90.02.16.16.14.11;  author shirriff;  state Exp;
  16. branches ;
  17. next     ;
  18.  
  19.  
  20. desc
  21. @@
  22.  
  23.  
  24. 1.2
  25. log
  26. @checking this in for Ken - JHH
  27. @
  28. text
  29. @/* 
  30.  * fsDisk.c --
  31.  *
  32.  *    Routines related to managing local disks.  Each partition of a local
  33.  *    disk (partitions are defined by a table on the disk header) is
  34.  *    called a ``domain''.  FsAttachDisk attaches a domain into the file
  35.  *    system, and FsDeattachDisk removes it.  A domain is given
  36.  *    a number the first time it is ever attached.  This is recorded on
  37.  *    the disk so it doesn't change between boots.  The domain number is
  38.  *    used to identify disks, and a domain number plus a file number is
  39.  *    used to identify files.  Fsdm_DomainFetch is used to get the state
  40.  *    associated with a disk, and Fsdm_DomainRelease releases the reference
  41.  *    on the state.  FsDetachDisk checks the references on domains in
  42.  *    the normal (non-forced) case so that active disks aren't detached.
  43.  *
  44.  * Copyright 1987 Regents of the University of California
  45.  * All rights reserved.
  46.  * Permission to use, copy, modify, and distribute this
  47.  * software and its documentation for any purpose and without
  48.  * fee is hereby granted, provided that the above copyright
  49.  * notice appear in all copies.  The University of California
  50.  * makes no representations about the suitability of this
  51.  * software for any purpose.  It is provided "as is" without
  52.  * express or implied warranty.
  53.  */
  54.  
  55. #ifdef notdef
  56. static char rcsid[] = "$Header: /sprite/src/boot/decprom/RCS/fsDisk.c,v 1.1 90/02/16 16:14:11 shirriff Exp Locker: shirriff $ SPRITE (Berkeley)";
  57. #endif not lint
  58.  
  59.  
  60. #include "sprite.h"
  61.  
  62. #include "fsBoot.h"
  63. #include "kernel/devDiskLabel.h"
  64. #include "kernel/dev.h"
  65. #include "kernel/devFsOpTable.h"
  66. #include "kernel/machMon.h"
  67. /*
  68.  * fsDevice is copied into all Fsio_FileIOHandles.  It is used by the drivers
  69.  * to get to the partition and geometry information for the disk.
  70.  */
  71. Fs_Device fsDevice;
  72.  
  73. /*
  74.  * fsDomainPtr and fsRootHandlePtr are used by Fs_Open.
  75.  */
  76. static Fsdm_Domain fsDomain;
  77. Fsdm_Domain *fsDomainPtr = &fsDomain;
  78. static Fsio_FileIOHandle fsRootHandle;
  79. Fsio_FileIOHandle *fsRootHandlePtr = &fsRootHandle;
  80.  
  81. /*
  82.  * Forward declarations.
  83.  */
  84. static int    InstallLocalDomain();
  85. void        AddDomainFlags();
  86. static Boolean    IsDecLabel();
  87.  
  88. /*
  89.  *----------------------------------------------------------------------
  90.  *
  91.  * FsAttachDisk --
  92.  *
  93.  *    Make a particular local disk partition correspond to a prefix.
  94.  *    This makes sure the disk is up, reads the domain header,
  95.  *    and calls the initialization routine for the block I/O module
  96.  *    of the disk's driver.  By the time this is called the device
  97.  *    initialization routines have already been called from Dev_Config
  98.  *    so the device driver knows how the disk is partitioned into
  99.  *    domains.  This routine sees if the domain is formatted correctly,
  100.  *    and if so attaches it to the set of domains.
  101.  *
  102.  * Results:
  103.  *    SUCCESS if the disk was readable and had a good domain header.
  104.  *
  105.  * Side effects:
  106.  *    Sets up the Fsdm_DomainInfo for the domain.
  107.  *
  108.  *----------------------------------------------------------------------
  109.  */
  110. ReturnStatus
  111. FsAttachDisk(fsDevicePtr)
  112.     Fs_Device *fsDevicePtr;        /* Global FS device descriptor */
  113. {
  114.     ReturnStatus status;        /* Error code */
  115.     register Address buffer;        /* Read buffer */
  116.     int headerSector;            /* Starting sector of domain header */
  117.     int numHeaderSectors;        /* Number of sectors in domain header */
  118.     int summarySector;            /* Sector of summary information. */
  119.     Fsdm_SummaryInfo *summaryInfoPtr;    /* Pointer to summary info. */
  120.     int amountRead;            /* Returned from read call */
  121.     int devType;            /* Device type index */
  122.  
  123.     /*
  124.      * Open the raw disk device so we can grub around in the header info.
  125.      */
  126.     Mach_MonPrintf("FsAttachDisk: ptr = %x\n", fsDevicePtr);
  127.     devType = DEV_TYPE_INDEX(fsDevicePtr->type);
  128.     status = (*devFsOpTable[devType].open)(&fsDevice);
  129.     if (status != SUCCESS) {
  130.     Mach_MonPrintf("Failure\n");
  131.     return(status);
  132.     }
  133.     Mach_MonPrintf("Mallocing\n");
  134.     buffer = (Address)malloc(DEV_BYTES_PER_SECTOR);
  135.     Mach_MonPrintf("Done mallocing\n");
  136.  
  137.     /*
  138.      * Read the 31st sector of the partition.  It has a copy of the
  139.      * 31st sector of the whole disk which describes how the rest of the
  140.      * domain's zero'th cylinder is layed out.
  141.      */
  142.     status = (*devFsOpTable[devType].read)(&fsDevice,
  143.         DEC_LABEL_SECTOR*DEV_BYTES_PER_SECTOR,
  144.         DEV_BYTES_PER_SECTOR, buffer, &amountRead);
  145.     if (status != SUCCESS) {
  146. #ifndef NO_PRINTF
  147.     Mach_MonPrintf("label (sector 31) read fail\n");
  148. #endif
  149.     return(status);
  150.     }
  151.     Mach_MonPrintf("Checking format\n");
  152.     /*
  153.      * Check for different disk formats, and figure out how the rest
  154.      * of the zero'th cylinder is layed out.
  155.      */
  156.     if (((Dec_DiskLabel *)buffer)->magic != DEC_LABEL_MAGIC) {
  157. #ifndef NO_PRINTF
  158.     Mach_MonPrintf("Bad magic <%x>\n", ((Dec_DiskLabel *)buffer)->magic);
  159. #endif
  160.     }
  161.  
  162.     headerSector = ((Dec_DiskLabel *)buffer)->domainSector;
  163.     numHeaderSectors = ((Dec_DiskLabel *)buffer)->numDomainSectors;
  164.     /*
  165.      * Read the domain header and save it with the domain state.
  166.      */
  167.     buffer = (Address)malloc(DEV_BYTES_PER_SECTOR * numHeaderSectors);
  168.     status = (*devFsOpTable[devType].read)(&fsDevice,
  169.         headerSector * DEV_BYTES_PER_SECTOR,
  170.         numHeaderSectors * DEV_BYTES_PER_SECTOR,
  171.         buffer, &amountRead);
  172.     Mach_MonPrintf("Read header\n");
  173.     if (status != SUCCESS) {
  174. #ifndef NO_PRINTF
  175.     Mach_MonPrintf("Domain fail\n");
  176. #endif
  177.     return(status);
  178.     } else if (((Fsdm_DomainHeader *)buffer)->magic != FSDM_DOMAIN_MAGIC) {
  179. #ifndef NO_PRINTF
  180.     Mach_MonPrintf("Bad magic <%x>\n",
  181.         ((Fsdm_DomainHeader *)buffer)->magic);
  182. #endif
  183.     return(FAILURE);
  184.     }
  185.  
  186.     fsDomainPtr->headerPtr = (Fsdm_DomainHeader *) buffer;
  187.  
  188.      /*
  189.      * Set up the ClientData part of *devicePtr to reference the
  190.      * Fsdm_Geometry part of the domain header.  This is used by the
  191.      * block I/O routines.
  192.      */
  193.     fsDevicePtr->data = (ClientData)&fsDomainPtr->headerPtr->geometry;
  194.  
  195.     /*
  196.      * Set up a file handle for the root directory.  What is important
  197.      * is the device info (for Block IO) and the file descriptor itself.
  198.      */
  199.     Mach_MonPrintf("Init'ing handle\n");
  200.     FsInitFileHandle(fsDomainPtr, FSDM_ROOT_FILE_NUMBER, fsRootHandlePtr);
  201.     Mach_MonPrintf("Done\n");
  202.     return(SUCCESS);
  203. }
  204.  
  205.  
  206. /*
  207.  *----------------------------------------------------------------------
  208.  *
  209.  * IsSunLabel --
  210.  *
  211.  *    Poke around in the input buffer and see if it looks like
  212.  *    a Sun format disk label.
  213.  *
  214.  * Results:
  215.  *    TRUE or FALSE
  216.  *
  217.  * Side effects:
  218.  *    None.
  219.  *
  220.  *----------------------------------------------------------------------
  221.  */
  222. #ifdef notdef
  223. static Boolean
  224. IsSunLabel(buffer)
  225.     Address buffer;    /* Buffer containing zero'th sector */
  226. {
  227.     register Sun_DiskLabel *sunLabelPtr;
  228.  
  229.     sunLabelPtr = (Sun_DiskLabel *)buffer;
  230.     if (sunLabelPtr->magic == SUN_DISK_MAGIC) {
  231.     /*
  232.      * Should check checkSum...
  233.      */
  234.     return(TRUE);
  235.     } else {
  236.     return(FALSE);
  237.     }
  238. }
  239. #endif
  240.  
  241. /*
  242.  *----------------------------------------------------------------------
  243.  *
  244.  * IsSpriteLabel --
  245.  *
  246.  *    Poke around in the input buffer and see if it looks like
  247.  *    a Sprite format disk header.
  248.  *
  249.  * Results:
  250.  *    TRUE or FALSE
  251.  *
  252.  * Side effects:
  253.  *    None.
  254.  *
  255.  *----------------------------------------------------------------------
  256.  */
  257. #ifdef notdef
  258. static Boolean
  259. IsSpriteLabel(buffer)
  260.     Address buffer;    /* Buffer containing zero'th sector */
  261. {
  262.     register FsDiskHeader *diskHeaderPtr;
  263.     register int index;
  264.     register int checkSum;
  265.  
  266.     diskHeaderPtr = (FsDiskHeader *)buffer;
  267.     if (diskHeaderPtr->magic == FSDM_DISK_MAGIC) {
  268.         return(TRUE);
  269.     }
  270.     }
  271.     return(FALSE);
  272. }
  273. #endif
  274.  
  275. /*
  276.  *----------------------------------------------------------------------
  277.  * The following routines are used by device drivers to map from block
  278.  * and sector numbers to disk addresses.  There are two sets, one for
  279.  * drivers that use logical sector numbers (i.e. SCSI) and the other
  280.  * for <cyl,head,sector> format disk addresses.
  281.  *----------------------------------------------------------------------
  282.  */
  283.  
  284. /*
  285.  *----------------------------------------------------------------------
  286.  *
  287.  * Fs_BlocksToSectors --
  288.  *
  289.  *    Convert from block indexes (actually, fragment indexes) to
  290.  *    sectors using the geometry information on the disk.  This
  291.  *    is a utility for block device drivers.
  292.  *
  293.  * Results:
  294.  *    The sector number that corresponds to the fragment index.
  295.  *    The caller has to make sure that its I/O doesn't cross a
  296.  *    filesystem block boundary.
  297.  *
  298.  * Side effects:
  299.  *    None.
  300.  *
  301.  *----------------------------------------------------------------------
  302.  */
  303. #define SECTORS_PER_FRAG    (FS_FRAGMENT_SIZE / DEV_BYTES_PER_SECTOR)
  304. #if defined(SCSI_DISK_BOOT) || defined(SUN_PROM_BOOT)
  305. int
  306. Fs_BlocksToSectors(fragNumber, data)
  307.     int fragNumber;    /* Fragment index to map into block index */
  308.     ClientData data;    /* ClientData from the device info */
  309. {
  310.     register Fsdm_Geometry *geoPtr;
  311.     register int sectorNumber;    /* The sector corresponding to the fragment */
  312.     register int cylinder;    /* The cylinder number of the fragment */
  313.     register int rotationalSet;    /* The rotational set with cylinder of frag */
  314.     register int blockNumber;    /* The block number within rotational set */
  315.  
  316.     geoPtr         = (Fsdm_Geometry *)data;
  317.     blockNumber        = fragNumber / FS_FRAGMENTS_PER_BLOCK;
  318.     cylinder        = blockNumber / geoPtr->blocksPerCylinder;
  319.     if (geoPtr->rotSetsPerCyl > 0) {
  320.     /*
  321.      * Do fancy rotational set mapping.
  322.      */
  323.     blockNumber        -= cylinder * geoPtr->blocksPerCylinder;
  324.     rotationalSet    = blockNumber / geoPtr->blocksPerRotSet;
  325.     blockNumber        -= rotationalSet * geoPtr->blocksPerRotSet;
  326.  
  327.     sectorNumber = geoPtr->sectorsPerTrack * geoPtr->numHeads * cylinder +
  328.               geoPtr->sectorsPerTrack * geoPtr->tracksPerRotSet *
  329.               rotationalSet +
  330.               geoPtr->blockOffset[blockNumber];
  331.     sectorNumber += (fragNumber % FS_FRAGMENTS_PER_BLOCK) * SECTORS_PER_FRAG;
  332.     } else {
  333.     /*
  334.      * Do straight-forward mapping.
  335.      */
  336.     sectorNumber = geoPtr->sectorsPerTrack * geoPtr->numHeads * cylinder +
  337.             fragNumber * SECTORS_PER_FRAG - cylinder * 
  338.             geoPtr->blocksPerCylinder * FS_FRAGMENTS_PER_BLOCK *
  339.             SECTORS_PER_FRAG;
  340.     }
  341.  
  342.     return(sectorNumber);
  343. }
  344. #endif
  345.  
  346. /*
  347.  *----------------------------------------------------------------------
  348.  *
  349.  * Fs_BlocksToDiskAddr --
  350.  *
  351.  *    Convert from block indexes (actually, fragment indexes) to
  352.  *    disk address (head, cylinder, sector) using the geometry information
  353.  *     on the disk.  This is a utility for block device drivers.
  354.  *
  355.  * Results:
  356.  *    The disk address that corresponds to the disk address.
  357.  *    The caller has to make sure that its I/O doesn't cross a
  358.  *    filesystem block boundary.
  359.  *
  360.  * Side effects:
  361.  *    None.
  362.  *
  363.  *----------------------------------------------------------------------
  364.  */
  365. #ifdef XYLOGICS_BOOT
  366. void
  367. Fs_BlocksToDiskAddr(fragNumber, data, diskAddrPtr)
  368.     int fragNumber;    /* Fragment index to map into block index */
  369.     ClientData data;    /* ClientData from the device info */
  370.     Dev_DiskAddr *diskAddrPtr;
  371. {
  372.     register Fsdm_Geometry *geoPtr;
  373.     register int sectorNumber;    /* The sector corresponding to the fragment */
  374.     register int cylinder;    /* The cylinder number of the fragment */
  375.     register int rotationalSet;    /* The rotational set with cylinder of frag */
  376.     register int blockNumber;    /* The block number within rotational set */
  377.  
  378.     geoPtr         = (Fsdm_Geometry *)data;
  379.     /*
  380.      * Map to block number because the rotational sets are laid out
  381.      * relative to blocks.  After that the cylinder is easy because we know
  382.      * blocksPerCylinder.  To get the head and sector we first get the
  383.      * rotational set (described in fsDisk.h) of the block and the
  384.      * block's sector offset (relative to the rotational set!).  This complex
  385.      * algorithm crops up because there isn't necessarily an even number
  386.      * of blocks per track.  The 'blockOffset' array in the geometry gives
  387.      * a sector index of each successive block in a rotational set. Finally,
  388.      * we can use the sectorsPerTrack to get the head and sector.
  389.      */
  390.     blockNumber        = fragNumber / FS_FRAGMENTS_PER_BLOCK;
  391.     cylinder        = blockNumber / geoPtr->blocksPerCylinder;
  392.     blockNumber        -= cylinder * geoPtr->blocksPerCylinder;
  393.     diskAddrPtr->cylinder = cylinder;
  394.  
  395.     rotationalSet    = blockNumber / geoPtr->blocksPerRotSet;
  396.     blockNumber        -= rotationalSet * geoPtr->blocksPerRotSet;
  397. /*
  398.  * The follow statment had to be broken into two because the compiler used
  399.  * register d2 to do the modulo operation, but wasn't saving its value.
  400.  */
  401.     sectorNumber    = geoPtr->sectorsPerTrack * geoPtr->tracksPerRotSet *
  402.               rotationalSet + geoPtr->blockOffset[blockNumber];
  403.     sectorNumber    +=
  404.             (fragNumber % FS_FRAGMENTS_PER_BLOCK) * SECTORS_PER_FRAG;
  405.  
  406.     diskAddrPtr->head    = sectorNumber / geoPtr->sectorsPerTrack;
  407.     diskAddrPtr->sector = sectorNumber -
  408.               diskAddrPtr->head * geoPtr->sectorsPerTrack;
  409. }
  410. #endif
  411.  
  412. /*
  413.  *----------------------------------------------------------------------
  414.  *
  415.  * Fs_SectorsToRawDiskAddr --
  416.  *
  417.  *      Convert from a sector offset to a raw disk address (cyl, head,
  418.  *      sector) using the geometry information on the disk.  This is a
  419.  *      utility for raw device drivers and does not pay attention to the
  420.  *      rotational position of filesystem disk blocks.
  421.  *
  422.  *    This should be moved to Dev
  423.  *
  424.  * Results:
  425.  *    The disk address that corresponds exactly to the byte offset.
  426.  *
  427.  * Side effects:
  428.  *    None.
  429.  *
  430.  *----------------------------------------------------------------------
  431.  */
  432. #ifdef XYLOGICS_BOOT
  433. int
  434. Fs_SectorsToRawDiskAddr(sector, numSectors, numHeads, diskAddrPtr)
  435.     int sector;        /* Sector number (counting from zero 'til the total
  436.              * number of sectors in the disk) */
  437.     int numSectors;    /* Number of sectors per track */
  438.     int numHeads;    /* Number of heads on the disk */
  439.     Dev_DiskAddr *diskAddrPtr;
  440. {
  441.     register int sectorsPerCyl;    /* The rotational set with cylinder of frag */
  442.  
  443.     sectorsPerCyl        = numSectors * numHeads;
  444.     diskAddrPtr->cylinder    = sector / sectorsPerCyl;
  445.     sector            -= diskAddrPtr->cylinder * sectorsPerCyl;
  446.     diskAddrPtr->head        = sector / numSectors;
  447.     diskAddrPtr->sector        = sector - numSectors * diskAddrPtr->head;
  448. }
  449. #endif
  450.  
  451.  
  452. /*
  453.  *----------------------------------------------------------------------
  454.  *
  455.  * FsDeviceBlockIO --
  456.  *
  457.  *    Map a file system block address to a block device block address 
  458.  *    perform the requested operation.
  459.  *
  460.  * NOTE: This routine is temporary and should be replaced when the file system
  461.  *     is converted to use the async block io interface.
  462.  *
  463.  * Results:
  464.  *    The return status of the operation.
  465.  *
  466.  * Side effects:
  467.  *    Blocks may be written or read.
  468.  *
  469.  *----------------------------------------------------------------------
  470.  */
  471.  
  472. ReturnStatus
  473. FsDeviceBlockIO(readWriteFlag, devicePtr, fragNumber, numFrags, buffer)
  474.     int readWriteFlag;        /* FS_READ or FS_WRITE */
  475.     Fs_Device *devicePtr;    /* Specifies device type to do I/O with */
  476.     int fragNumber;        /* CAREFUL, fragment index, not block index.
  477.                  * This is relative to start of device. */
  478.     int numFrags;        /* CAREFUL, number of fragments, not blocks */
  479.     Address buffer;        /* I/O buffer */
  480. {
  481.     ReturnStatus status;    /* General return code */
  482.     int firstSector;        /* Starting sector of transfer */
  483.     DevBlockDeviceRequest    request;
  484.     int                transferCount;
  485.     int                devType;
  486.  
  487.     devType = DEV_TYPE_INDEX(devicePtr->type);
  488.     if ((fragNumber % FS_FRAGMENTS_PER_BLOCK) != 0) {
  489.     /*
  490.      * The I/O doesn't start on a block boundary.  Transfer the
  491.      * first few extra fragments to get things going on a block boundary.
  492.      */
  493.     register int extraFrags;
  494.  
  495.     extraFrags = FS_FRAGMENTS_PER_BLOCK -
  496.             (fragNumber % FS_FRAGMENTS_PER_BLOCK);
  497.     if (extraFrags > numFrags) {
  498.         extraFrags = numFrags;
  499.     }
  500.     firstSector = Fs_BlocksToSectors(fragNumber, devicePtr->data);
  501.     status = (*devFsOpTable[devType].read)(devicePtr,
  502.         firstSector * DEV_BYTES_PER_SECTOR,
  503.         extraFrags * FS_FRAGMENT_SIZE, buffer, &transferCount);
  504.     if (status != SUCCESS) {
  505. #ifndef NO_PRINTF
  506.         Mach_MonPrintf("Fragment read failure\n");
  507. #endif
  508.     }
  509.     extraFrags = transferCount / FS_FRAGMENT_SIZE;
  510.     fragNumber += extraFrags;
  511.     buffer += transferCount;
  512.     numFrags -= extraFrags;
  513.     }
  514.     if (numFrags > 0) {
  515.     /*
  516.      * Transfer the left over fragments.
  517.      */
  518.     firstSector = Fs_BlocksToSectors(fragNumber, devicePtr->data);
  519.     status = (*devFsOpTable[devType].read)(devicePtr,
  520.         firstSector * DEV_BYTES_PER_SECTOR,
  521.         numFrags * FS_FRAGMENT_SIZE, buffer, &transferCount);
  522.     if (status != SUCCESS) {
  523. #ifndef NO_PRINTF
  524.         Mach_MonPrintf("Last fragment read failure\n");
  525. #endif
  526.     }
  527.     }
  528.     return(status);
  529. }
  530.  
  531. @
  532.  
  533.  
  534. 1.1
  535. log
  536. @Initial revision
  537. @
  538. text
  539. @d28 1
  540. a28 1
  541. static char rcsid[] = "$Header: /sprite/src/boot/dsprom/RCS/fsDisk.c,v 1.1 90/02/13 23:40:32 shirriff Exp $ SPRITE (Berkeley)";
  542. d98 1
  543. d102 1
  544. d105 1
  545. d107 1
  546. d123 1
  547. d144 1
  548. d171 1
  549. d173 1
  550. @
  551.